#include "CManorBattleMgr.h"
#include "MsgBattle.pb.h"
#include "MsgManorBattle.pb.h"
#include "commmsg.h"
#include "../mainctrl.h"
#include "../simpleconfig/CMonsterConfig.h"
#include "../data/CPlayerCacheData.h"
#include "../item/CDropItem.h"
#include "../status/CUserStatus.h"
#include "../battle/CBattleData.h"
#include "../battle/CBattleRole.h"
#include "../battle/CBattleMgr.h"
#include "../clan/CClanEntry.h"
#include "../map/CMapView.h"
#include "../act/CActCfg.h"
#include "../cmdinner/CCmdInnerManorBattle.h"

void CManorBattleMgr::SetMap()
{
    int iIndex = 0;

    if (_stData.GetMapSize() <= 0)
    {
        iIndex = CMainCtrl::m_pstMain->m_stActMgr.FindActCfg(
            ACT_ID_MANOR_BATTLE);
        if (iIndex < 0){CT_ERROR(("Manor Battle No Act Cfg!")); return;}
        
        CActCfgData& stActData =
            CMainCtrl::m_pstMain->m_stActMgr.GetActCfg(iIndex);
        
        iIndex = CMainCtrl::m_pstMain->m_stSceneMgr.FindSceneCfg(
            stActData.GetSceneID());
        if (iIndex < 0){CT_ERROR(("Manor Battle No Scene Cfg!")); return;}
        
        CSceneCfgData& stSceneData =
            CMainCtrl::m_pstMain->m_stSceneMgr.GetSceneCfg(iIndex);

        CManorBattleMapUnit stMapUnit;
        stMapUnit.SetAttackPosX(stSceneData.GetEnterX());
        stMapUnit.SetAttackPosY(stSceneData.GetEnterY());
        stMapUnit.SetDefendPosX(stSceneData.GetDeadBorderX());
        stMapUnit.SetDefendPosY(stSceneData.GetDeadBorderY());

        stMapUnit.SetBlessStatus(MANOR_BATTLE_BLESS_STATUS_ONE);
        stMapUnit.SetMapID(stSceneData.GetMapID());
        _stData.AddMap(stMapUnit);

        stMapUnit.SetBlessStatus(MANOR_BATTLE_BLESS_STATUS_TWO);
        stMapUnit.SetMapID(stSceneData.GetRelayMapID());
        _stData.AddMap(stMapUnit);

        stMapUnit.SetBlessStatus(MANOR_BATTLE_BLESS_STATUS_THR);
        stMapUnit.SetMapID(stSceneData.GetAuxRelayMapID());
        _stData.AddMap(stMapUnit);
    }
}

bool CManorBattleMgr::IsValidStatForMon()
{
    return (_stData.GetBattleStat() >= 0 &&
            _stData.GetBattleStat() < _stData.GetMonSize());
}

bool CManorBattleMgr::IsValidStatForMon(int iStatForMon)
{
    return (iStatForMon >= 0 && iStatForMon < _stData.GetMonSize());
}

bool CManorBattleMgr::IsValidStatForMap()
{
    return (_stData.GetBattleStat() >= 0 &&
            _stData.GetBattleStat() < _stData.GetMapSize());
}

bool CManorBattleMgr::IsValidStatForMap(int iStatForMap)
{
    return (iStatForMap >= 0 && iStatForMap < _stData.GetMapSize());
}

bool CManorBattleMgr::IsManorBattleScene(const unsigned int uiMapID)
{
    SetMap();

    for (int i = 0; i < _stData.GetMapSize(); ++i)
    {
        CManorBattleMapUnit& stMapUnit = _stData.GetMap(i);
        if (stMapUnit.GetMapID() == uiMapID)
        {
            return true;
        }
    }

    return false;
}

bool CManorBattleMgr::IsRoleInManorBattle(unsigned int uiGID)
{
    SetMap();

    //这个活动开启时候只判断当前场景 担心加速情形下场景跳转过程存在问题
    if (CMainCtrl::m_pstMain->m_stActMgr.IsActOpen(ACT_ID_MANOR_BATTLE))
    {
        if (IsValidStatForMap())
        {
            CManorBattleMapUnit& stMap =
                _stData.GetMap(_stData.GetBattleStat());
            if (CMainCtrl::m_pstMain->m_stMapViews.IsRoleInMap(
                    stMap.GetMapID(), uiGID))
            {
                return true;
            }
        }
    }
    else
    {
        for (int i = 0; i < _stData.GetMapSize(); ++i)
        {
            CManorBattleMapUnit& stMapUnit = _stData.GetMap(i);
            if (CMainCtrl::m_pstMain->m_stMapViews.IsRoleInMap(
                    stMapUnit.GetMapID(), uiGID))
            {
                return true;
            }
        }
    }

    return false;
}

bool CManorBattleMgr::IsMapIDNeedUpdateDB(const unsigned int uiMapID)
{
    if (IsManorBattleScene(uiMapID))
    {
        return false;
    }

    return true;
}

//活动开启 强制开启和到期开启走同样的逻辑
int CManorBattleMgr::ActOpen(CActCfgData& stActCfgData)
{
    int iRet = 0;
    int iIndex = 0;
    int iWorldLevel = CMainCtrl::m_pstMain->m_stArenaMgr.GetWorldBossLevel();

    CManorBattleZoneData& stZone =
        CMainCtrl::m_pstMain->m_stZoneOnlineData._stZoneData._stManorBattle;

    iIndex = CMainCtrl::m_pstMain->m_stSceneMgr.FindSceneCfg(
        stActCfgData.GetSceneID());
    CT_CHECK(iIndex, ERROR_SCENE_EMPTY_CFG);

    CSceneCfgData& stSceneData =
        CMainCtrl::m_pstMain->m_stSceneMgr.GetSceneCfg(iIndex);

    Clear();//清掉所有数据

    SetMap();
    _stData.SetBattleStat(MANOR_BATTLE_STAT_ONE);
    _stData.SetStatEndTime(
        CMainCtrl::m_pstMain->m_iNow + MANOR_BATTLE_PREPARE_SEC);
    _stData.SetBombStatus(MANOR_BATTLE_BOMB_STATUS);

    _stData.SetBombLevel(stZone._iBombLevel + 1);//炸弹等级

    CManorBattleMonUnit stMonsterUnit;
    CMonsterGroupConfigData stMonsterGroup;

    //黑铁之堡
    iRet = CMainCtrl::m_pstMain->m_stMonsterConfigMgr.GetMonsterGroupConfig(
        stSceneData.GetMonGroupID(), iWorldLevel - MANOR_BATTLE_LEVEL_ONE,
        stMonsterGroup);
    CT_RETURN(iRet);

    stMonsterUnit.SetHP(
        stMonsterGroup._astMonsters[0]._stMonster._stMonsterDefaultAttr._uiHP);
    stMonsterUnit.SetMaxHP(
        stMonsterGroup._astMonsters[0]._stMonster._stMonsterDefaultAttr._uiHP);
    stMonsterUnit.SetLevel(iWorldLevel - MANOR_BATTLE_LEVEL_ONE);
    stMonsterUnit.SetGroupID(stSceneData.GetMonGroupID());

    _stData.AddMonster(stMonsterUnit);

    //白银之角
    iRet = CMainCtrl::m_pstMain->m_stMonsterConfigMgr.GetMonsterGroupConfig(
        stSceneData.GetLeftGroupID(), iWorldLevel - MANOR_BATTLE_LEVEL_TWO,
        stMonsterGroup);
    CT_RETURN(iRet);

    stMonsterUnit.SetHP(
        stMonsterGroup._astMonsters[0]._stMonster._stMonsterDefaultAttr._uiHP);
    stMonsterUnit.SetMaxHP(
        stMonsterGroup._astMonsters[0]._stMonster._stMonsterDefaultAttr._uiHP);
    stMonsterUnit.SetLevel(iWorldLevel - MANOR_BATTLE_LEVEL_TWO);
    stMonsterUnit.SetGroupID(stSceneData.GetLeftGroupID());

    _stData.AddMonster(stMonsterUnit);

    //黄金之城
    iRet = CMainCtrl::m_pstMain->m_stMonsterConfigMgr.GetMonsterGroupConfig(
        stSceneData.GetRightGroupID(), iWorldLevel - MANOR_BATTLE_LEVEL_THR,
        stMonsterGroup);
    CT_RETURN(iRet);

    stMonsterUnit.SetHP(
        stMonsterGroup._astMonsters[0]._stMonster._stMonsterDefaultAttr._uiHP);
    stMonsterUnit.SetMaxHP(
        stMonsterGroup._astMonsters[0]._stMonster._stMonsterDefaultAttr._uiHP);
    stMonsterUnit.SetLevel(iWorldLevel - MANOR_BATTLE_LEVEL_THR);
    stMonsterUnit.SetGroupID(stSceneData.GetRightGroupID());

    _stData.AddMonster(stMonsterUnit);

    //家族战
    unsigned int uiDefendClanID = stZone._uiClanID;//正常逻辑是取ZoneData中保存的结果ID
    CManorBattleClanUnit stClanUnit;
    if (uiDefendClanID > 0)
    {
        iIndex = CMainCtrl::m_pstMain->m_stClanMgr.GetClanIndexByClanId(
            uiDefendClanID);
        if (iIndex >= 0)
        {
            CClanEntry& stClanEntry =
                CMainCtrl::m_pstMain->m_stClanMgr._stClanEntryHash[iIndex];

            stClanUnit.Clear();
            stClanUnit.SetAcademy(stClanEntry._ucAcademyType);
            stClanUnit.SetGID(stClanEntry._uiClanId);
            stClanUnit.SetClanName(stClanEntry._szName.Get());

            _stData.AddClan(stClanUnit);
        }
        else
        {
            CT_ERROR(("Clan(%u) not in Entry Hash!",uiDefendClanID));
        }
    }

    for (int i = 0;
            i < CMainCtrl::m_pstMain->m_stClanBattleMgr.GetClanRankSize()
            && i < MAX_MANOR_BATTLE_ATK_CLAN_COUNT; ++i)
    {
        CClanBattleRankData& stClanBattleUnit =
            CMainCtrl::m_pstMain->m_stClanBattleMgr.GetClanRankUnit(i);
    
        if ((uiDefendClanID > 0 && stClanBattleUnit._uiID == uiDefendClanID)
            || stClanBattleUnit._uiID <= 0)
        {
            continue;
        }

        stClanUnit.Clear();
        stClanUnit.SetAcademy(stClanBattleUnit._ucAcademy);
        stClanUnit.SetGID(stClanBattleUnit._uiID);
        stClanUnit.SetClanName(stClanBattleUnit._szClanName.Get());

        _stData.AddClan(stClanUnit);
    }

    //内网测试时候没有家族战 取家族排名榜
    if (CMainCtrl::m_pstMain->m_stClanBattleMgr.GetClanRankSize() <= 0)
    {
        for (int i = 0;
                i < CMainCtrl::m_pstMain->m_stClanMgr._astClanRank.Size()
                && i < MAX_MANOR_BATTLE_ATK_CLAN_COUNT; ++i)
        {
            iIndex = CMainCtrl::m_pstMain->m_stClanMgr._astClanRank[i];
            CClanEntry& stClanEntry =
                CMainCtrl::m_pstMain->m_stClanMgr._stClanEntryHash[iIndex];
    
            if ((uiDefendClanID > 0 && stClanEntry._uiClanId == uiDefendClanID)
                || stClanEntry._uiClanId <= 0)
            {
                continue;
            }
            
            stClanUnit.Clear();
            stClanUnit.SetAcademy(stClanEntry._ucAcademyType);
            stClanUnit.SetGID(stClanEntry._uiClanId);
            stClanUnit.SetClanName(stClanEntry._szName.Get());
            
            _stData.AddClan(stClanUnit);
        }
    }

    return 0;
}

//活动关闭 提前关闭和到期关闭走同样的逻辑
int CManorBattleMgr::ActClose(CActCfgData& stActCfgData)
{
    int iIndex = 0;

    CDropItem stClanItem;
    CDropItem stRoleItem;
    CManorBattleUnit stUnit;

    if (_stData.GetBattleStat() > MANOR_BATTLE_STAT_THR)
    {
        //表示黄金之城被攻破
        stUnit._bIsBreak = true;
        stUnit._iSubCmd = CMD_MANOR_BATTLE_SUB_TIME_OVER;
    }
    else
    {
        //表示黄金之城没攻破 活动到期结束
        stUnit._bIsBreak = false;
        stUnit._iSubCmd = CMD_MANOR_BATTLE_SUB_TIME_OVER;
    }

    //这里决定所有场景都下发
    for (int i = 0; i < _stData.GetMapSize(); ++i)
    {
        CManorBattleMapUnit& stMap = _stData.GetMap(i);
        stUnit._uiMapID = stMap.GetMapID();
        NotifyAllSceneRole(stUnit);
    }

    //领地战个人礼包 以及 领地战个人称号
    iIndex = _stCfg.FindConfig(
        (MANOR_BATTLE_ITEM_ROLE_RANK + _stData.GetBattleStat()));
    if (iIndex >= 0)
    {
        CManorBattleCfgData& stCfgData = _stCfg.GetConfig(iIndex);
        for (int i = 0; i < stCfgData.GetItemSize(); ++i)
        {
            CDropItemData& stItemData = stCfgData.GetItem(i);
            stRoleItem.Drop(stItemData);
        }
    }
    else
    {
        CT_ERROR(("Monster kill but config error (stat%d)",
            _stData.GetBattleStat()));
    }
    if (stRoleItem.Size() > 0)
    {
        stRoleItem.SetOssModule(OSS_MODULE_MANOR_BATTLE);
        for (int i = 0; i < _stRank.GetDefendSize(); ++i)
        {
            CManorBattleDefUnit& stUnit = _stRank.GetDefendUnit(i);
            CMainCtrl::m_pstMain->m_stItemMgr.DropItem(NULL, stUnit.GetGID(),
                stRoleItem);

            if (0 == i)
            {
                CMainCtrl::m_pstMain->m_stRoleMgr.DropTitle(stUnit.GetGID(),
                    ROLE_TITLE_MANOR_DEFEND,
                    (CMainCtrl::m_pstMain->m_iNow +
                        MANOR_BATTLE_TITLE_LAST_TIME));
            }
        }
        for (int i = 0; i < _stRank.GetAttackSize(); ++i)
        {
            CManorBattleAtkUnit& stUnit = _stRank.GetAttackUnit(i);
            CMainCtrl::m_pstMain->m_stItemMgr.DropItem(NULL, stUnit.GetGID(),
                stRoleItem);

            if (0 == i)
            {
                CMainCtrl::m_pstMain->m_stRoleMgr.DropTitle(stUnit.GetGID(),
                    ROLE_TITLE_MANOR_ATTACK,
                    (CMainCtrl::m_pstMain->m_iNow +
                        MANOR_BATTLE_TITLE_LAST_TIME));
            }
        }
    }

    //领地战领地归属
    CManorBattleZoneData& stZone =
        CMainCtrl::m_pstMain->m_stZoneOnlineData._stZoneData._stManorBattle;
    if (stUnit._bIsBreak && _stRank.GetAttackClanSize() > 0) //被击破
    {
        CManorBattleClanUnit& stClanUnit = _stRank.GetAttackClan(0);
        stZone._uiClanID = stClanUnit.GetGID();
        stZone._iBombLevel = 0;
    }
    else
    {
        ++stZone._iBombLevel;
        if (stZone._iBombLevel > MANOR_BATTLE_BOMB_LEVEL_MAX)
        {
            stZone._iBombLevel = MANOR_BATTLE_BOMB_LEVEL_MAX;
        }

        stClanItem.Clear();
        iIndex = _stCfg.FindConfig(
            (MANOR_BATTLE_ITEM_BELONG_ONE + _stData.GetBattleStat()));
        if (iIndex >= 0)
        {
            CManorBattleCfgData& stCfgData = _stCfg.GetConfig(iIndex);
            for (int i = 0; i < stCfgData.GetItemSize(); ++i)
            {
                CDropItemData& stItemData = stCfgData.GetItem(i);
                stClanItem.Drop(stItemData);
            }
        }
        else
        {
            CT_ERROR(("Monster kill but config error (stat%d)",
                _stData.GetBattleStat()));
        }

        if (stClanItem.Size() > 0)
        {
            stClanItem.SetOssModule(OSS_MODULE_MANOR_BATTLE);
            CMainCtrl::m_pstMain->m_stClanMgr.AddItem(stZone._uiClanID,
                stClanItem);
        }
    }

    CMainCtrl::m_pstMain->m_stRewardBackMgr.UpdateZoneDataToDB();

    for (int i = 0; i < _stRank.GetAttackClanSize(); ++i)
    {
        CManorBattleClanUnit& stClanUnit = _stRank.GetAttackClan(i);

        stClanItem.Clear();

        iIndex = _stCfg.FindConfig((MANOR_BATTLE_ITEM_ATTACK_CLAN + i));
        if (iIndex >= 0)
        {
            CManorBattleCfgData& stCfgData = _stCfg.GetConfig(iIndex);
            for (int i = 0; i < stCfgData.GetItemSize(); ++i)
            {
                CDropItemData& stItemData = stCfgData.GetItem(i);
                stClanItem.Drop(stItemData);
            }
        }
        else
        {
            CT_ERROR(("Monster kill but config error (rank %d)",i));
        }

        if (stClanItem.Size() > 0)
        {
            stClanItem.SetOssModule(OSS_MODULE_MANOR_BATTLE);
            CMainCtrl::m_pstMain->m_stClanMgr.AddItem(stClanUnit.GetGID(),
                stClanItem);
        }
    }

    return 0;
}

int CManorBattleMgr::EnterScene(unsigned int& uiMapID, unsigned short& usPosX,
        unsigned short& usPosY, CPlayerDetailInfo& stPlayerDetail)
{
    //后端修正前端进入的地图ID以及XY坐标

    if (!IsManorBattleScene(uiMapID))
    {
        return 0;
    }

    if (IsRoleInManorBattle(stPlayerDetail._uiGID))
    {
        return 0; //已经在场景内的不限制
    }

    if (!CMainCtrl::m_pstMain->m_stActMgr.IsActOpen(ACT_ID_MANOR_BATTLE))
    {
        return ERROR_ACT_NOT_OPEN; //非活动期间不允许进入
    }

    int iCamp = _stData.GetClanCamp(stPlayerDetail._stUserClan._uiClanId);
    if (ENM_MANOR_BATTLE_CAMP_NONE == iCamp)
    {
        return ERROR_MANOR_BATTLE_NOT_IN_LIST; //非家族战前十家族不能参加
    }

    if (!IsValidStatForMap())
    {
        return ERROR_MANOR_BATTLE_ACT_STAT; //活动阶段错误
    }

    CManorBattleMapUnit& stMap = _stData.GetMap(_stData.GetBattleStat());
    uiMapID = stMap.GetMapID();

    CManorBattleUnit stUnit;
    stUnit._bNotifySelf = false;
    stUnit._uiMainGID = stPlayerDetail._uiGID;
    stUnit._uiMapID = uiMapID;

    if (ENM_MANOR_BATTLE_CAMP_DEFEND == iCamp)
    {
        usPosX = stMap.GetDefendPosX();
        usPosY = stMap.GetDefendPosY();
        
        _stData.AddDefendRoleNum(1);
        stUnit._iSubCmd = CMD_MANOR_BATTLE_SUB_SCENE_INFO;
    }        
    else if (ENM_MANOR_BATTLE_CAMP_ATTACK == iCamp)
    {
        usPosX = stMap.GetAttackPosX();
        usPosY = stMap.GetAttackPosY();

        _stData.AddAttackRoleNum(1);
        stUnit._iSubCmd = CMD_MANOR_BATTLE_SUB_SCENE_INFO;
    }

    if (stUnit._iSubCmd > 0)
    {
        NotifyAllSceneRole(stUnit);
    }

    return 0;
}

int CManorBattleMgr::LeaveScene(unsigned int uiGID)
{
    CCmdInnerManorBattle* pstCmd =
        (CCmdInnerManorBattle*)CT_CMDFACTORY->CreateCmd(
            ID_MAIN_INNER_MANOR_BATTLE);
    if (!pstCmd)
    {
        CT_ERROR(("create CCmdInnerManorBattle error"));
        return RET_SYS_NULL_POINTER;
    }

    pstCmd->pstMainCtrl = CMainCtrl::m_pstMain;
    pstCmd->_stUnit.Clear();
    pstCmd->_stUnit._uiMainGID = uiGID;
    pstCmd->_stUnit._iSubCmd = CMD_INNER_MANOR_BATTLE_LEAVE;

    return pstCmd->Do(NULL);
}

int CManorBattleMgr::LeaveScene(CPlayerDetailInfo& stPlayerDetail,
        CManorBattleUnit& stUnit)
{
    if (!CMainCtrl::m_pstMain->m_stActMgr.IsActOpen(ACT_ID_MANOR_BATTLE))
    {
        return 0; //暂时不出错返回
    }

    int iCamp = _stData.GetClanCamp(stPlayerDetail._stUserClan._uiClanId);
    if (ENM_MANOR_BATTLE_CAMP_DEFEND == iCamp)
    {
        _stData.AddDefendRoleNum(-1);
        stUnit._iTargetCamp = DeleteTargetListUnit(stPlayerDetail);
    }
    else if (ENM_MANOR_BATTLE_CAMP_ATTACK == iCamp)
    {
        _stData.AddAttackRoleNum(-1);
        stUnit._iTargetCamp = DeleteTargetListUnit(stPlayerDetail);
    }

    return 0;
}

int CManorBattleMgr::CheckManorBattle(CPlayerCacheData& stPlayerCache)
{
    int iIndex = 0;

    if (!CMainCtrl::m_pstMain->m_stActMgr.IsActOpen(ACT_ID_MANOR_BATTLE))
    {
        return ERROR_ACT_NOT_OPEN; //非活动期间返回错误码
    }

    if (!IsValidStatForMon())
    {
        return ERROR_MANOR_BATTLE_ACT_STAT; //活动阶段错误
    }

    CManorBattleMonUnit& stMon =
        _stData.GetMonster(_stData.GetBattleStat());
    if (stMon.GetHP() <= 0)
    {
        return ERROR_MANOR_BATTLE_MONSTER_DIE;
    }

    if (!IsValidStatForMap())
    {
        return ERROR_MANOR_BATTLE_ACT_STAT; //活动阶段错误
    }

    if (_stData.GetStatEndTime() > CMainCtrl::m_pstMain->m_iNow)
    {
        return ERROR_MANOR_BATTLE_PREPARE_TIME;
    }

    if (!IsRoleInManorBattle(stPlayerCache._uiGID))
    {
        return ERROR_MANOR_BATTLE_NOT_IN_MAP;
    }

    iIndex = CMainCtrl::m_pstMain->m_stActMgr.FindActStatusCfg(
        ACT_ID_MANOR_BATTLE);
    CT_CHECK(iIndex, ERROR_ACT_STATUS_EMPTY_CFG);
    
    CActStatusCfgData& stActStatusCfg =
        CMainCtrl::m_pstMain->m_stActMgr.GetActStatusCfg(iIndex);

    //是否处于死亡状态
    iIndex = CMainCtrl::m_pstMain->m_stStatusMgr.FindStatus(
        stPlayerCache, stActStatusCfg.GetDeadID());
    if (iIndex >= 0)
    {
        CStatusUnit& stStatusUnit =
            CMainCtrl::m_pstMain->m_stStatusMgr.GetStatus(
                stPlayerCache, iIndex);

        //死亡状态到期 主动清除
        if (stStatusUnit.GetEndTime() <= CMainCtrl::m_pstMain->m_iNow)
        {
            CMainCtrl::m_pstMain->m_stStatusMgr.DelStatus(stPlayerCache,
                stActStatusCfg.GetDeadID(), true);
            //这里欠考虑 需要通知前端由灰色变回亮色
        }
        else
        {
            return ERROR_STATUS_DEAD_NO_BATTLE;
        }
    }

    iIndex = CMainCtrl::m_pstMain->m_stStatusMgr.FindStatus(
        stPlayerCache, stActStatusCfg.GetCoolingID());
    if (iIndex >= 0)
    {
        CStatusUnit& stStatusUnit =
            CMainCtrl::m_pstMain->m_stStatusMgr.GetStatus(
                stPlayerCache, iIndex);

        //战斗冷却到期 主动清除
        if (stStatusUnit.GetEndTime() <= CMainCtrl::m_pstMain->m_iNow)
        {
            CMainCtrl::m_pstMain->m_stStatusMgr.DelStatus(stPlayerCache,
                stActStatusCfg.GetCoolingID(), true);
        }
        else
        {
            return ERROR_STATUS_IN_FIGHT_CD;
        }
    }

    return 0;
}

//双方都可能主动发起攻击 这里使用A表示主动攻击者 B表示被击者
int CManorBattleMgr::ManorBattle(CPlayerBaseInfo& stPlayerBaseA,
        CPlayerDetailInfo& stPlayerDetailA, CPlayerOnlineData& stPlayerOnlineA,
        CPlayerCacheData& stPlayerCacheA, CPlayerBaseInfo& stPlayerBaseB,
        CPlayerDetailInfo& stPlayerDetailB, CPlayerOnlineData& stPlayerOnlineB,
        CPlayerCacheData& stPlayerCacheB, CManorBattleInfo& stInfo,
        bool bIsAttackRole, int iRoleACamp, MsgReqManorBattle& stReq,
        MsgAnsManorBattle& stAns, MsgAnsManorBattle& stObjAns)
{
    int iRet = 0;
    int iIndex = 0;
    int iOldMonHP = 0;
    int iNewMonHP = 0;
    int iNew = -1;
    int iOld = -1;
    int iScoreA = 0;
    int iScoreB = 0;
    int iTargetCamp = 0;
    unsigned int uiMapID = 0;
    CManorBattleUnit stUnit;

    //CheckManorBattle已检查IsValidStatForMap()这里直接使用
    CManorBattleMapUnit& stMap =
        _stData.GetMap(_stData.GetBattleStat());
    uiMapID = stMap.GetMapID();

    //CheckManorBattle已检查IsValidStatForMon()这里直接使用
    CManorBattleMonUnit& stMon =
        _stData.GetMonster(_stData.GetBattleStat());
    if (stMon.GetHP() <= 0)
    {
        return ERROR_MANOR_BATTLE_MONSTER_DIE;
    }
    iOldMonHP = stMon.GetHP();

    iIndex = CMainCtrl::m_pstMain->m_stActMgr.FindActCfg(
        ACT_ID_MANOR_BATTLE);
    if (iIndex < 0)
    {
        CT_ERROR(("manor battle act(%d) config empty!", ACT_ID_MANOR_BATTLE));
        return ERROR_ACT_EMPTY_CFG;
    }
    CActCfgData& stActCfgData =
        CMainCtrl::m_pstMain->m_stActMgr.GetActCfg(iIndex);

    iIndex = CMainCtrl::m_pstMain->m_stActMgr.FindActStatusCfg(
        ACT_ID_MANOR_BATTLE);
    CT_CHECK(iIndex, ERROR_ACT_STATUS_EMPTY_CFG);
    
    CActStatusCfgData& stActStatusCfg =
        CMainCtrl::m_pstMain->m_stActMgr.GetActStatusCfg(iIndex);

    MsgBattleResult* pstBattleResult = stAns.mutable_battle_result();
    MsgBattleResult* pstBattleResultObj = stObjAns.mutable_battle_result();
    if (!pstBattleResult || !pstBattleResultObj)
    {
        return RET_SYS_NULL_POINTER;
    }

    CBattleRoleList stRoleListA;
    CBattleRoleList stRoleListB;

    iRet = CMainCtrl::m_pstMain->m_stBattleMgr.TransPlayerAndPartner(
        stPlayerBaseA, stPlayerDetailA, stPlayerOnlineA, stRoleListA, true);
    CT_RETURN(iRet);

    if (bIsAttackRole)
    {
        iRet = CMainCtrl::m_pstMain->m_stBattleMgr.TransPlayerAndPartner(
            stPlayerBaseB, stPlayerDetailB, stPlayerOnlineB, stRoleListB,
            false);
        CT_RETURN(iRet);
    }
    else
    {
        CMonsterGroupConfigData stMonsterGroup;
        iRet = CMainCtrl::m_pstMain->m_stMonsterConfigMgr.GetMonsterGroupConfig(
            stMon.GetGroupID(), stMon.GetLevel(), stMonsterGroup);
        CT_RETURN(iRet);

        iRet = CMainCtrl::m_pstMain->m_stBattleMgr.TransGroupMonster(
            stMonsterGroup, stRoleListB, false);
        CT_RETURN(iRet);
    }

    ReviseBeforeBattle(stPlayerCacheA, stRoleListA,
        (ENM_MANOR_BATTLE_CAMP_DEFEND == iRoleACamp));
    ReviseBeforeBattle(stPlayerCacheB, stRoleListB,
        (ENM_MANOR_BATTLE_CAMP_ATTACK == iRoleACamp));

    iRet = CMainCtrl::m_pstMain->m_stBattleMgr.DealPvPBattle(stRoleListA,
        stRoleListB, *pstBattleResult, stActCfgData.GetType());
    CT_RETURN(iRet);

    if (stReq.has_battle_ext_info())
    {
    	(*pstBattleResult->mutable_battle_ext_info()) =
            stReq.battle_ext_info();
    }

    if (bIsAttackRole)
    {
        (*pstBattleResultObj) = (*pstBattleResult);
    }

    ResetHPAfterBattle(stPlayerCacheA, stRoleListA);
    ResetHPAfterBattle(stPlayerCacheB, stRoleListB);

    iNewMonHP = stMon.GetHP();

    CalcBattleScore(stPlayerBaseA, stPlayerBaseB, bIsAttackRole,
        (BATTLE_RESULT_WIN == pstBattleResult->result()), iRoleACamp, iScoreA,
        iScoreB);

    if (ENM_MANOR_BATTLE_CAMP_DEFEND == iRoleACamp)
    {
        if (iScoreA > 0)
        {
            stPlayerCacheA._stManorBattleRole.AddScore(iScoreA);

            CManorBattleDefUnit stDefUnit;
            stDefUnit.SetScore(stPlayerCacheA._stManorBattleRole.GetScore());
            stDefUnit.SetAcademy(stPlayerBaseA._ucAcademy);
            stDefUnit.SetGID(stPlayerBaseA._uiGID);
            stDefUnit.SetRoleName(stPlayerBaseA._sRoleName.Get());

            _stRank.DefendRankUpdate(stDefUnit, iOld, iNew);

            stUnit.Clear();
            stUnit._iSubCmd = CMD_MANOR_BATTLE_SUB_RANK;
            stUnit._uiMapID = uiMapID;
            stInfo.AddUnit(stUnit);
        }

        if (iScoreB > 0)
        {
            stPlayerCacheB._stManorBattleRole.AddScore(iScoreB);

            CManorBattleAtkUnit stAtkUnit;
            stAtkUnit.SetScore(stPlayerCacheB._stManorBattleRole.GetScore());
            stAtkUnit.SetAcademy(stPlayerBaseB._ucAcademy);
            stAtkUnit.SetGID(stPlayerBaseB._uiGID);
            stAtkUnit.SetRoleName(stPlayerBaseB._sRoleName.Get());

            _stRank.AttackRankUpdate(stAtkUnit, iOld, iNew);

            iIndex = _stData.FindClan(stPlayerDetailB._stUserClan._uiClanId);
            if (iIndex > 0) //这里跳过0 因为约定0元素是防守方家族
            {
                CManorBattleClanUnit& stClanUnit = _stData.GetClan(iIndex);
                stClanUnit.AddScore(iScoreB);
                _stRank.AttackClanUpdate(stClanUnit, iOld, iNew);
            }

            stUnit.Clear();
            stUnit._iSubCmd = CMD_MANOR_BATTLE_SUB_RANK;
            stUnit._uiMapID = uiMapID;
            stInfo.AddUnit(stUnit);
        }
    }
    else if (ENM_MANOR_BATTLE_CAMP_ATTACK == iRoleACamp)
    {
        if (iScoreA > 0)
        {
            stPlayerCacheA._stManorBattleRole.AddScore(iScoreA);

            CManorBattleAtkUnit stAtkUnit;
            stAtkUnit.SetScore(stPlayerCacheA._stManorBattleRole.GetScore());
            stAtkUnit.SetAcademy(stPlayerBaseA._ucAcademy);
            stAtkUnit.SetGID(stPlayerBaseA._uiGID);
            stAtkUnit.SetRoleName(stPlayerBaseA._sRoleName.Get());

            _stRank.AttackRankUpdate(stAtkUnit, iOld, iNew);

            iIndex = _stData.FindClan(stPlayerDetailA._stUserClan._uiClanId);
            if (iIndex > 0) //这里跳过0 因为约定0元素是防守方家族
            {
                CManorBattleClanUnit& stClanUnit = _stData.GetClan(iIndex);
                stClanUnit.AddScore(iScoreA);
                _stRank.AttackClanUpdate(stClanUnit, iOld, iNew);
            }

            stUnit.Clear();
            stUnit._iSubCmd = CMD_MANOR_BATTLE_SUB_RANK;
            stUnit._uiMapID = uiMapID;
            stInfo.AddUnit(stUnit);
        }

        if (iScoreB > 0)
        {
            stPlayerCacheB._stManorBattleRole.AddScore(iScoreB);

            CManorBattleDefUnit stDefUnit;
            stDefUnit.SetScore(stPlayerCacheB._stManorBattleRole.GetScore());
            stDefUnit.SetAcademy(stPlayerBaseB._ucAcademy);
            stDefUnit.SetGID(stPlayerBaseB._uiGID);
            stDefUnit.SetRoleName(stPlayerBaseB._sRoleName.Get());

            _stRank.DefendRankUpdate(stDefUnit, iOld, iNew);

            stUnit.Clear();
            stUnit._iSubCmd = CMD_MANOR_BATTLE_SUB_RANK;
            stUnit._uiMapID = uiMapID;
            stInfo.AddUnit(stUnit);
        }
    }

    if (!bIsAttackRole && iNewMonHP != iOldMonHP)
    {
        stUnit.Clear();
        stUnit._iSubCmd = CMD_MANOR_BATTLE_SUB_MONSTER;
        stUnit._uiMapID = uiMapID;
        stUnit._iStatForMon = _stData.GetBattleStat();
        stInfo.AddUnit(stUnit);
    }

    //单场攻击个人奖励
    CDropItem stDropItemA;
    CDropItem stDropItemB;
    if (!bIsAttackRole && iNewMonHP < iOldMonHP)
    {
        CalcAttackMonReward(iOldMonHP - iNewMonHP, stMon.GetMaxHP(),
            stMon.GetLevel(), stDropItemA);

        if (iNewMonHP <= 0) //击杀城门怪的奖励
        {
            iIndex = _stCfg.FindConfig(
                (MANOR_BATTLE_ITEM_MON_KILL_ONE + _stData.GetBattleStat()));
            if (iIndex >= 0)
            {
                CManorBattleCfgData& stCfgData = _stCfg.GetConfig(iIndex);
                for (int i = 0; i < stCfgData.GetItemSize(); ++i)
                {
                    CDropItemData& stItemData = stCfgData.GetItem(i);
                    stDropItemA.Drop(stItemData);
                }
            }
            else
            {
                CT_ERROR(("Monster kill but config error (stat%d)",
                    _stData.GetBattleStat()));
            }
        }

        if (stDropItemA.Size() > 0)
        {
            stDropItemA.SetOssModule(OSS_MODULE_MANOR_BATTLE);
            CMainCtrl::m_pstMain->m_stItemMgr.DropItem(NULL,
                stPlayerBaseA._uiGID, stDropItemA);
        }
    }
    if (iScoreA > 0)
    {
        stDropItemA.DropItem(ITEM_TYPE_MANOR_SCORE, iScoreA);
    }
    if (iScoreB > 0)
    {
        stDropItemB.DropItem(ITEM_TYPE_MANOR_SCORE, iScoreB);
    }

    //攻破地图的领地收益
    if (!bIsAttackRole && iNewMonHP <= 0)
    {
        CDropItem stClanItem;
        iIndex = _stCfg.FindConfig(
            (MANOR_BATTLE_ITEM_BELONG_ONE + _stData.GetBattleStat()));
        if (iIndex >= 0)
        {
            CManorBattleCfgData& stCfgData = _stCfg.GetConfig(iIndex);
            for (int i = 0; i < stCfgData.GetItemSize(); ++i)
            {
                CDropItemData& stItemData = stCfgData.GetItem(i);
                stClanItem.Drop(stItemData);
            }
        }
        else
        {
            CT_ERROR(("Monster kill but config error (stat%d)",
                _stData.GetBattleStat()));
        }

        if (stClanItem.Size() > 0)
        {
            stClanItem.SetOssModule(OSS_MODULE_MANOR_BATTLE);
            CMainCtrl::m_pstMain->m_stClanMgr.AddItem(
                stPlayerDetailA._stUserClan._uiClanId, stClanItem);
        }
    }

    //以下处理死亡冷却 场景怪物被击杀不施加死亡和战斗冷却
    if (iNewMonHP > 0)
    {
        if (stRoleListA.IsAllRoleDataDead())
        {
            DealStatusAfterBattle(stPlayerCacheA, stActStatusCfg);

            stUnit.Clear();
            stUnit._iSubCmd = CMD_MANOR_BATTLE_SUB_DEAD;
            stUnit._uiMapID = uiMapID;
            stUnit._uiMainGID = stPlayerBaseA._uiGID;
            stInfo.AddUnit(stUnit);

            iTargetCamp = DeleteTargetListUnit(stPlayerDetailA);
            if (iTargetCamp > 0)
            {
                stUnit.Clear();
                stUnit._iSubCmd = CMD_MANOR_BATTLE_SUB_TARGET;
                stUnit._uiMapID = uiMapID;
                stUnit._iTargetCamp = iTargetCamp;
                stUnit._uiMainGID = stPlayerBaseA._uiGID;
                stInfo.AddUnit(stUnit);
            }
        }
        else if (iScoreA > 0)
        {
            UpdateTargetList(stPlayerBaseA, stPlayerDetailA, stPlayerCacheA,
                stInfo);
        }
        
        if (bIsAttackRole && stRoleListB.IsAllRoleDataDead())
        {
            DealStatusAfterBattle(stPlayerCacheB, stActStatusCfg);
            
            stUnit.Clear();
            stUnit._iSubCmd = CMD_MANOR_BATTLE_SUB_DEAD;
            stUnit._uiMapID = uiMapID;
            stUnit._uiMainGID = stPlayerBaseB._uiGID;
            stInfo.AddUnit(stUnit);
            
            iTargetCamp = DeleteTargetListUnit(stPlayerDetailB);
            if (iTargetCamp > 0)
            {
                stUnit.Clear();
                stUnit._iSubCmd = CMD_MANOR_BATTLE_SUB_TARGET;
                stUnit._uiMapID = uiMapID;
                stUnit._iTargetCamp = iTargetCamp;
                stUnit._uiMainGID = stPlayerBaseB._uiGID;
                stInfo.AddUnit(stUnit);
            }
        }
        else if (bIsAttackRole && iScoreB > 0)
        {
            UpdateTargetList(stPlayerBaseB, stPlayerDetailB, stPlayerCacheB,
                stInfo);
        }
    }
    else
    {
        //因为想走ActClose作为统一结算入口 活动到期结束和提前攻破结束都走那边
        if (MANOR_BATTLE_STAT_THR == _stData.GetBattleStat())
        {
            stUnit.Clear();
            stUnit._iSubCmd = CMD_MANOR_BATTLE_SUB_TIME_OVER;
            stUnit._uiMapID = uiMapID;
            stInfo.AddUnit(stUnit);
        }
        else
        {
            stUnit.Clear();
            stUnit._iSubCmd = CMD_MANOR_BATTLE_SUB_SCENE_OVER;
            stUnit._uiMapID = uiMapID;
            stInfo.AddUnit(stUnit);

            _stData.SetStatEndTime(
                CMainCtrl::m_pstMain->m_iNow + MANOR_BATTLE_PREPARE_SEC);
        }

        _stData.SetBattleStat(_stData.GetBattleStat() + 1);
    }

    SetBattleTip(stPlayerBaseA, stPlayerCacheA, stPlayerBaseB, stPlayerCacheB,
        stAns, stObjAns, bIsAttackRole,
        (BATTLE_RESULT_WIN == pstBattleResult->result()), iOldMonHP - iNewMonHP,
        stDropItemA, stDropItemB);

    return 0;
}

int CManorBattleMgr::ReviseBeforeBattle(CPlayerCacheData& stPlayerCache,
        CBattleRoleList& stRoleList, bool bIsDefend)
{
    int iHP = 0;
    int iHPMax = 0;
    int iIndex = 0;
    int iRatio = 0;
    int iStatusID = 0;
    int iBattleStat = _stData.GetBattleStat();
    int64 i64RatioTmp = 0;

    CStatusObj stStatusObj;
    stStatusObj._iResID = MANOR_BATTLE_BOMB_STATUS + _stData.GetBombLevel() - 1;
    stStatusObj._iAddNum = 1;
    stStatusObj._iSrcType = STATUS_SOURCE_OBJ_ACT_CFG;

    //飞火流星在这里加入在战斗中生效
    //护佑状态是在这里修正而不是在战斗中
    if (MANOR_BATTLE_STAT_THR == iBattleStat)
    {
        iStatusID = MANOR_BATTLE_BLESS_STATUS_THR;   //黄金护佑状态ID
    }
    else if (MANOR_BATTLE_STAT_TWO == iBattleStat)
    {
        iStatusID = MANOR_BATTLE_BLESS_STATUS_TWO;   //白银护佑状态ID
    }
    else
    {
        iStatusID = MANOR_BATTLE_BLESS_STATUS_ONE;   //黑铁护佑状态ID
    }
    
    iIndex = CMainCtrl::m_pstMain->m_stStatusMgr.FindSkillEffect(iStatusID);
    if (iIndex >= 0)
    {
        CSkillEffect& stSkillEff =
            CMainCtrl::m_pstMain->m_stStatusMgr.GetSkillEffect(iIndex);
        iRatio = stSkillEff.GetData();
    }

    for (int i = 0; i < stRoleList._astRoleData.Size(); ++i)
    {
        iHPMax = 0;
        CBattleRoleData& stRoleData = stRoleList._astRoleData[i];
        if (GAME_OBJ_TYPE_PLAYER == stRoleData._chType)
        {
            iHP = stPlayerCache._stManorBattleRole.GetRoleHP();
            if (bIsDefend && iRatio > 0)
            {
                i64RatioTmp = INT64_1 * stRoleData._iHPMax *
                    (BATTLE_RATE_SKILL_PERCENT + iRatio);
                i64RatioTmp /= BATTLE_RATE_SKILL_PERCENT;
                iHPMax = (int)(i64RatioTmp);
            }

            if (!bIsDefend)
            {
                stRoleData._stStatusList._astStatus.AddOneItem(stStatusObj);
            }

            if (iHP > 0)
            {
                stRoleData._iHP = iHP;
            }
            else if (iHPMax > 0)
            {
                stRoleData._iHP = iHPMax;
            }

            if (iHPMax > 0)
            {
                stRoleData._iHPMax = iHPMax;
            }
        }
        else if (GAME_OBJ_TYPE_PARTNER == stRoleData._chType)
        {
            iHP = stPlayerCache._stManorBattleRole.GetPartnerHP(
                stRoleData._uiObjID);
            if (bIsDefend && iRatio > 0)
            {
                i64RatioTmp = INT64_1 * stRoleData._iHPMax *
                    (BATTLE_RATE_SKILL_PERCENT + iRatio);
                i64RatioTmp /= BATTLE_RATE_SKILL_PERCENT;
                iHPMax = (int)(i64RatioTmp);
            }

            if (!bIsDefend)
            {
                stRoleData._stStatusList._astStatus.AddOneItem(stStatusObj);
            }

            if (iHP > 0)
            {
                stRoleData._iHP = iHP;
            }
            else if (iHPMax > 0)
            {
                stRoleData._iHP = iHPMax;
            }

            if (iHPMax > 0)
            {
                stRoleData._iHPMax = iHPMax;
            }
        }
        else if (GAME_OBJ_TYPE_MONSTER == stRoleData._chType)
        {
            //CheckManorBattle已检查IsValidStatForMon()这里直接使用
            CManorBattleMonUnit& stMon =
                _stData.GetMonster(_stData.GetBattleStat());
            stRoleData._iHP = stMon.GetHP();
        }
    }

    return 0;
}

int CManorBattleMgr::ResetHPAfterBattle(CPlayerCacheData& stPlayerCache,
        CBattleRoleList& stRoleList)
{
    for (int i = 0; i < stRoleList._astRoleData.Size(); ++i)
    {
        CBattleRoleData& stRoleData = stRoleList._astRoleData[i];
        if (GAME_OBJ_TYPE_PLAYER == stRoleData._chType)
        {
            stPlayerCache._stManorBattleRole.SetRoleHP(stRoleData._iHP);
        }
        else if (GAME_OBJ_TYPE_PARTNER == stRoleData._chType)
        {
            stPlayerCache._stManorBattleRole.SetPartnerHP(stRoleData._uiObjID,
                stRoleData._iHP);
        }
        else if (GAME_OBJ_TYPE_MONSTER == stRoleData._chType)
        {
            //CheckManorBattle已检查IsValidStatForMon()这里直接使用
            CManorBattleMonUnit& stMon =
                _stData.GetMonster(_stData.GetBattleStat());
            stMon.SetHP(stRoleData._iHP);
        }
    }

    return 0;
}

void CManorBattleMgr::DealStatusAfterBattle(CPlayerCacheData& stPlayerCache,
        CActStatusCfgData& stActStatusCfg)
{
    int iRet = 0;

    //死亡状态没有叠加层数 直接修改到期时间
    iRet = CMainCtrl::m_pstMain->m_stStatusMgr.AddStatus(
        stPlayerCache, stActStatusCfg.GetDeadID(),
        CMainCtrl::m_pstMain->m_iNow + MANOR_BATTLE_DEAD_WAIT_TIME,
        ACT_ID_MANOR_BATTLE, false);
    if (iRet) {CT_ERROR(("role add dead status error(%d)",iRet));}

    //战斗冷却没有叠加层数 直接修改到期时间
    iRet = CMainCtrl::m_pstMain->m_stStatusMgr.AddStatus(
        stPlayerCache, stActStatusCfg.GetCoolingID(),
        CMainCtrl::m_pstMain->m_iNow + MANOR_BATTLE_FIGHT_WAIT_TIME,
        ACT_ID_MANOR_BATTLE, false);
    if (iRet) {CT_ERROR(("role add fight cool status error(%d)",iRet));}

    if (CMainCtrl::m_pstMain->m_stStatusMgr.IsNeedSendStatusList(
            stActStatusCfg.GetDeadID()) || 
        CMainCtrl::m_pstMain->m_stStatusMgr.IsNeedSendStatusList(
            stActStatusCfg.GetCoolingID()))
    {
        CMainCtrl::m_pstMain->m_stStatusMgr.NotifyUserStatusToSelfByGID(
            stPlayerCache._uiGID);
    }
}

void CManorBattleMgr::CalcBattleScore(CPlayerBaseInfo& stPlayerBaseA,
        CPlayerBaseInfo& stPlayerBaseB, bool bIsAttackRole, bool bIsAWin,
        int iRoleACamp, int& iScoreA, int& iScoreB)
{
    int iCampRatioA = 0;
    int iCampRatioB = 0;
    int64 i64ScoreA = 0;
    int64 i64ScoreB = 0;

    if (ENM_MANOR_BATTLE_CAMP_DEFEND == iRoleACamp)
    {
        iCampRatioA = MANOR_BATTLE_SCORE_DEFEND_RATIO;
        iCampRatioB = MANOR_BATTLE_SCORE_ATTACK_RATIO;
    }
    else
    {
        iCampRatioB = MANOR_BATTLE_SCORE_DEFEND_RATIO;
        iCampRatioA = MANOR_BATTLE_SCORE_ATTACK_RATIO;
    }

    if (bIsAWin)
    {
        if (bIsAttackRole)
        {
            i64ScoreA = (INT64_1 * stPlayerBaseB._shLevel *
                MANOR_BATTLE_SCORE_LEVEL_RATIO * iCampRatioA);
            i64ScoreB = (INT64_1 * stPlayerBaseA._shLevel * iCampRatioB);
        }
        else
        {
            CManorBattleMonUnit& stMon =
                _stData.GetMonster(_stData.GetBattleStat());

            i64ScoreA = (INT64_1 * stMon.GetLevel() *
                MANOR_BATTLE_SCORE_LEVEL_RATIO * iCampRatioA *
                MANOR_BATTLE_SCORE_MONSTER_RATIO);
        }
    }
    else
    {
        if (bIsAttackRole)
        {
            i64ScoreA = (INT64_1 * stPlayerBaseB._shLevel * iCampRatioA);
            i64ScoreB = (INT64_1 * stPlayerBaseA._shLevel *
                MANOR_BATTLE_SCORE_LEVEL_RATIO * iCampRatioB);
        }
        else
        {
            CManorBattleMonUnit& stMon =
                _stData.GetMonster(_stData.GetBattleStat());

            i64ScoreA = (INT64_1 * stMon.GetLevel() * iCampRatioA *
                MANOR_BATTLE_SCORE_MONSTER_RATIO);
        }
    }

    i64ScoreA /= MANOR_BATTLE_SCORE_DIVISOR_RATIO;
    i64ScoreB /= MANOR_BATTLE_SCORE_DIVISOR_RATIO;

    iScoreA = (int)i64ScoreA;
    iScoreB = (int)i64ScoreB;
}

//写成通用 沿用世界等级以及世界BOSS的掉落
void CManorBattleMgr::CalcAttackMonReward(int iAttackVal, int iMonMaxHP,
        int iWorldLevel, CDropItem& stDropItem)
{
    int iIndex = 0;
    int iTotalExp = 0;
    int iTotalRepu = 0;
    int iTotalContri = 0;
    int iTotalSilver = 0;

    if (iAttackVal <= 0 || iMonMaxHP <= 0)
    {
        return;
    }

    int64 i64RatioTmp = INT64_1 * iAttackVal * BATTLE_RATE_SKILL_PERCENT;
    i64RatioTmp /= iMonMaxHP;
    int iAttackKey = (int)(i64RatioTmp);
    if (iAttackKey <= 0)
    {
        iAttackKey = 1;
    }

    iIndex = CMainCtrl::m_pstMain->m_stWorldBossMgr.FindAttackConfig(
        iAttackKey);
    if (iIndex < 0)
    {
        CT_ERROR(("boss attack hp(%d) max hp(%d) attack id(%d) but cfg empty",
            iAttackVal, iMonMaxHP, iAttackKey));
        return;
    }

    CWorldBossCfgAttack& stAttackCfg =
        CMainCtrl::m_pstMain->m_stWorldBossMgr.GetAttackConfig(iIndex);

    iIndex = CMainCtrl::m_pstMain->m_stWorldBossMgr.FindRewardConfig(
        iWorldLevel);
    if (iIndex < 0)
    {
        CT_ERROR(("reward level(%d) config empty", iWorldLevel));
        return;
    }

    CWorldBossCfgReward& stRewardCfg =
        CMainCtrl::m_pstMain->m_stWorldBossMgr.GetRewardConfig(iIndex);

    i64RatioTmp = INT64_1 * stAttackCfg.GetReputationBase() *
        stRewardCfg.GetReputationRatio();
    i64RatioTmp /= BATTLE_RATE_SKILL_PERCENT;
    iTotalRepu = (int)(i64RatioTmp);

    i64RatioTmp = INT64_1 * stAttackCfg.GetExpBase() *
        stRewardCfg.GetExpRatio();
    i64RatioTmp /= BATTLE_RATE_SKILL_PERCENT;
    iTotalExp = (int)(i64RatioTmp);

    i64RatioTmp = INT64_1 * stAttackCfg.GetContribuBase() *
        stRewardCfg.GetContribuRatio();
    i64RatioTmp /= BATTLE_RATE_SKILL_PERCENT;
    iTotalContri = (int)(i64RatioTmp);

    i64RatioTmp = INT64_1 * stAttackCfg.GetSilverBase() *
        stRewardCfg.GetSilverRatio();
    i64RatioTmp /= BATTLE_RATE_SKILL_PERCENT;
    iTotalSilver = (int)(i64RatioTmp);

    CDropItemData stDropUnit;
    if (iTotalRepu > 0)
    {
        stDropUnit._ucItemType = ITEM_TYPE_REPUTATION;
        stDropUnit._iItemCount = iTotalRepu;
        stDropItem.Drop(stDropUnit);
    }

    if (iTotalExp > 0)
    {
        stDropUnit._ucItemType = ITEM_TYPE_EXP;
        stDropUnit._iItemCount = iTotalExp;
        stDropItem.Drop(stDropUnit);
    }

    if (iTotalContri > 0)
    {
        stDropUnit._ucItemType = ITEM_TYPE_CONTRIBUTION;
        stDropUnit._iItemCount = iTotalContri;
        stDropItem.Drop(stDropUnit);
    }

    if (iTotalSilver > 0)
    {
        stDropUnit._ucItemType = ITEM_TYPE_SILVER;
        stDropUnit._iItemCount = iTotalSilver;
        stDropItem.Drop(stDropUnit);
    }
}

void CManorBattleMgr::SetBattleTip(CPlayerBaseInfo& stPlayerBaseA,
        CPlayerCacheData& stPlayerCacheA, CPlayerBaseInfo& stPlayerBaseB,
        CPlayerCacheData& stPlayerCacheB, MsgAnsManorBattle& stAns,
        MsgAnsManorBattle& stObjAns, bool bIsAttackRole, bool bIsAWin,
        int iAttackVal, CDropItem& stDropItemA, CDropItem& stDropItemB)
{
    MsgManorBattleTip* pstAnsTip = stAns.mutable_battle_tip();
    MsgManorBattleTip* pstObjAnsTip = stObjAns.mutable_battle_tip();
    if (!pstAnsTip || !pstObjAnsTip)
    {
        CT_ERROR(("A role(%u) or B role(%u) MsgManorBattleTip Pointer Null!",
            stPlayerBaseA._uiGID, stPlayerBaseB._uiGID));
        return;
    }

    if (bIsAWin)
    {
        stPlayerCacheA._stManorBattleRole.AddSeriesKill(1);

        pstAnsTip->set_is_win(1);
        pstAnsTip->set_series_win(
            stPlayerCacheA._stManorBattleRole.GetSeriesKill());

        if (bIsAttackRole)
        {
            stPlayerCacheB._stManorBattleRole.SetSeriesKill(0);
            pstObjAnsTip->set_is_win(0);
            pstObjAnsTip->set_series_win(0);

            pstAnsTip->set_is_role(1);
            pstAnsTip->set_attack_val(0);
            pstAnsTip->set_object_name(stPlayerBaseB._sRoleName.Get());
        
            pstObjAnsTip->set_is_role(1);
            pstObjAnsTip->set_attack_val(0);
            pstObjAnsTip->set_object_name(stPlayerBaseA._sRoleName.Get());
        }
    }
    else
    {
        stPlayerCacheA._stManorBattleRole.SetSeriesKill(0);
        pstAnsTip->set_is_win(0);
        pstAnsTip->set_series_win(0);

        if (bIsAttackRole)
        {
            stPlayerCacheB._stManorBattleRole.AddSeriesKill(1);
            pstObjAnsTip->set_is_win(1);
            pstObjAnsTip->set_series_win(
                stPlayerCacheB._stManorBattleRole.GetSeriesKill());

            pstAnsTip->set_is_role(1);
            pstAnsTip->set_attack_val(0);
            pstAnsTip->set_object_name(stPlayerBaseB._sRoleName.Get());
        
            pstObjAnsTip->set_is_role(1);
            pstObjAnsTip->set_attack_val(0);
            pstObjAnsTip->set_object_name(stPlayerBaseA._sRoleName.Get());
        }
    }

    if (!bIsAttackRole)
    {
        pstAnsTip->set_is_role(0);
        pstAnsTip->set_attack_val(iAttackVal);
    }

    stDropItemA.GetPBMsg(stPlayerBaseA._uiGID,
        *(pstAnsTip->mutable_battle_award()));

    stDropItemB.GetPBMsg(stPlayerBaseB._uiGID,
        *(pstObjAnsTip->mutable_battle_award()));
}

int CManorBattleMgr::GetMapShow(MsgAnsManorBattle& stAns)
{
    if (!CMainCtrl::m_pstMain->m_stActMgr.IsActOpen(ACT_ID_MANOR_BATTLE))
    {
        return ERROR_ACT_NOT_OPEN; //非活动期间返回错误码
    }

    MsgManorBattleShow* pstMapShow = stAns.mutable_show_info();
    if (!pstMapShow)
    {
        return RET_SYS_NULL_POINTER; //系统空指针
    }

    if (IsValidStatForMap())
    {
        CManorBattleMapUnit& stMap = _stData.GetMap(_stData.GetBattleStat());
        pstMapShow->set_fight_map(stMap.GetMapID());
    }
    else
    {
        pstMapShow->set_fight_map(0);
    }

    if (_stData.GetClanSize() > 0)
    {
        CManorBattleClanUnit& stClan = _stData.GetClan(0);//约定0元素为防守家族
        pstMapShow->set_clan_name(stClan.GetClanName());
    }

    return 0;
}

void CManorBattleMgr::UpdateRoleInfo(CPlayerCacheData& stPlayerCache)
{
    int iActEndTime = CMainCtrl::m_pstMain->m_stActMgr.GetEndTime(
            ACT_ID_MANOR_BATTLE);
    
    if (stPlayerCache._stManorBattleRole.GetEndTime() != iActEndTime)
    {
        stPlayerCache._stManorBattleRole.Clear();
        stPlayerCache._stManorBattleRole.SetEndTime(iActEndTime);
    }
}

int CManorBattleMgr::GetInfo(CPlayerDetailInfo& stPlayerDetail,
        CPlayerCacheData& stPlayerCache, MsgAnsManorBattle& stAns)
{
    if (!CMainCtrl::m_pstMain->m_stActMgr.IsActOpen(ACT_ID_MANOR_BATTLE))
    {
        return ERROR_ACT_NOT_OPEN; //非活动期间返回错误码
    }

    if (!IsRoleInManorBattle(stPlayerDetail._uiGID))
    {
        return ERROR_MANOR_BATTLE_NOT_IN_MAP;
    }

    if (!IsValidStatForMon())
    {
        return ERROR_MANOR_BATTLE_ACT_STAT; //活动阶段错误
    }

    int iCamp = _stData.GetClanCamp(stPlayerDetail._stUserClan._uiClanId);
    if (ENM_MANOR_BATTLE_CAMP_NONE == iCamp)
    {
        return ERROR_MANOR_BATTLE_NOT_IN_LIST; //非家族战前十家族不能参加
    }

    GetCommInfo(stPlayerDetail, stAns);

    GetSceneInfo(stAns);

    GetRoleInfo(stPlayerCache, stAns);

    GetMonsterInfo(_stData.GetBattleStat(), stAns);

    GetRank(stPlayerCache, stAns);

    GetMapShow(stAns);

    return 0;
}

//获取目标列表的入口
int CManorBattleMgr::GetTargetList(CPlayerBaseInfo& stPlayerBase,
        CPlayerDetailInfo& stPlayerDetail, CPlayerCacheData& stPlayerCache,
        CManorBattleInfo& stInfo, MsgAnsManorBattle& stAns)
{
    if (!CMainCtrl::m_pstMain->m_stActMgr.IsActOpen(ACT_ID_MANOR_BATTLE))
    {
        return ERROR_ACT_NOT_OPEN; //非活动期间返回错误码
    }

    if (!IsValidStatForMap())
    {
        return ERROR_MANOR_BATTLE_ACT_STAT; //活动阶段错误
    }

    if (_stData.GetStatEndTime() > CMainCtrl::m_pstMain->m_iNow)
    {
        return ERROR_MANOR_BATTLE_PREPARE_TIME;
    }

    if (!IsRoleInManorBattle(stPlayerBase._uiGID))
    {
        return ERROR_MANOR_BATTLE_NOT_IN_MAP;
    }

    int iCamp = _stData.GetClanCamp(stPlayerDetail._stUserClan._uiClanId);
    if (ENM_MANOR_BATTLE_CAMP_NONE == iCamp)
    {
        return ERROR_MANOR_BATTLE_NOT_IN_LIST; //非家族战前十家族不能参加
    }

    CManorBattleUnit stUnit;

    UpdateRoleInfo(stPlayerCache);

    UpdateTargetList(stPlayerBase, stPlayerDetail, stPlayerCache, stInfo);

    if (ENM_MANOR_BATTLE_CAMP_DEFEND == iCamp) //我所在阵营为防守方
    {
        GetAttackTargetList(stAns);
    }
    else if (ENM_MANOR_BATTLE_CAMP_ATTACK == iCamp) //我所在阵营为进攻方
    {
        GetDefendTargetList(stAns);
    }

    GetCommInfo(stPlayerDetail, stAns);

    return 0;
}

int CManorBattleMgr::LeaveTargetList(CPlayerDetailInfo& stPlayerDetail,
        CManorBattleInfo& stInfo, MsgAnsManorBattle& stAns)
{
    if (!CMainCtrl::m_pstMain->m_stActMgr.IsActOpen(ACT_ID_MANOR_BATTLE))
    {
        return ERROR_ACT_NOT_OPEN; //非活动期间返回错误码
    }

    if (!IsValidStatForMap())
    {
        return ERROR_MANOR_BATTLE_ACT_STAT; //活动阶段错误
    }

    CManorBattleMapUnit& stMap =
        _stData.GetMap(_stData.GetBattleStat());

    if (!IsRoleInManorBattle(stPlayerDetail._uiGID))
    {
        return ERROR_MANOR_BATTLE_NOT_IN_MAP;
    }

    int iCamp = _stData.GetClanCamp(stPlayerDetail._stUserClan._uiClanId);
    if (ENM_MANOR_BATTLE_CAMP_NONE == iCamp)
    {
        return ERROR_MANOR_BATTLE_NOT_IN_LIST; //非家族战前十家族不能参加
    }

    int iTargetCamp = DeleteTargetListUnit(stPlayerDetail);
    if (iTargetCamp > 0)
    {
        CManorBattleUnit stUnit;
        stUnit._iSubCmd = CMD_MANOR_BATTLE_SUB_TARGET;
        stUnit._uiMapID = stMap.GetMapID();
        stUnit._iTargetCamp = iTargetCamp;
        stInfo.AddUnit(stUnit);
    }

    GetCommInfo(stPlayerDetail, stAns);

    return 0;
}

//获取防守方目标列表
void CManorBattleMgr::GetDefendTargetList(MsgAnsManorBattle& stAns)
{
    for (int i = 0; i < _stRank.GetDefendListSize(); ++i)
    {
        MsgBattleTargetUnit* pstUnit = stAns.add_target_list();
        if (!pstUnit){CT_ERROR(("MsgBattleTargetUnit Pointer Null!"));continue;}

        CManorBattleDefTag& stDefTag = _stRank.GetDefendTag(i);
        pstUnit->set_academy(stDefTag.GetAcademy());
        pstUnit->set_score(stDefTag.GetScore());
        pstUnit->set_name(stDefTag.GetRoleName());
        pstUnit->set_gid(stDefTag.GetGID());
        pstUnit->set_level(stDefTag.GetLevel());
    }
}

//获取进攻方目标列表
void CManorBattleMgr::GetAttackTargetList(MsgAnsManorBattle& stAns)
{
    for (int i = 0; i < _stRank.GetAttackListSize(); ++i)
    {
        MsgBattleTargetUnit* pstUnit = stAns.add_target_list();
        if (!pstUnit){CT_ERROR(("MsgBattleTargetUnit Pointer Null!"));continue;}

        CManorBattleAtkTag& stAtkTag = _stRank.GetAttackTag(i);
        pstUnit->set_academy(stAtkTag.GetAcademy());
        pstUnit->set_score(stAtkTag.GetScore());
        pstUnit->set_name(stAtkTag.GetRoleName());
        pstUnit->set_gid(stAtkTag.GetGID());
        pstUnit->set_level(stAtkTag.GetLevel());
    }
}

void CManorBattleMgr::UpdateTargetList(CPlayerBaseInfo& stPlayerBase,
        CPlayerDetailInfo& stPlayerDetail, CPlayerCacheData& stPlayerCache,
        CManorBattleInfo& stInfo)
{
    if (!IsValidStatForMap())
    {
        return; //活动阶段错误
    }

    CManorBattleMapUnit& stMap =
        _stData.GetMap(_stData.GetBattleStat());

    int iCamp = _stData.GetClanCamp(stPlayerDetail._stUserClan._uiClanId);
    if (ENM_MANOR_BATTLE_CAMP_NONE == iCamp)
    {
        return; //非家族战前十家族不能参加
    }

    CManorBattleUnit stUnit;

    int iOldOrder = -1;
    int iNewOrder = -1;

    if (ENM_MANOR_BATTLE_CAMP_DEFEND == iCamp) //我所在阵营为防守方
    {
        CManorBattleDefTag stDefTag;
        stDefTag.SetScore(stPlayerCache._stManorBattleRole.GetScore());
        stDefTag.SetLevel(stPlayerBase._shLevel);
        stDefTag.SetAcademy(stPlayerBase._ucAcademy);
        stDefTag.SetGID(stPlayerBase._uiGID);
        stDefTag.SetRoleName(stPlayerBase._sRoleName.Get());

        _stRank.DefendTagUpdate(stDefTag, iOldOrder, iNewOrder);

        //如果积分有变排名不变 这里没有触发下发 需要战斗那边触发
        if (iNewOrder >= 0 && iOldOrder != iNewOrder)
        {
            stUnit.Clear();
            stUnit._iSubCmd = CMD_MANOR_BATTLE_SUB_TARGET;
            stUnit._uiMapID = stMap.GetMapID();
            stUnit._iTargetCamp = ENM_MANOR_BATTLE_CAMP_DEFEND;
            stInfo.AddUnit(stUnit);
        }
    }
    else if (ENM_MANOR_BATTLE_CAMP_ATTACK == iCamp) //我所在阵营为进攻方
    {
        CManorBattleAtkTag stAtkTag;
        stAtkTag.SetScore(stPlayerCache._stManorBattleRole.GetScore());
        stAtkTag.SetLevel(stPlayerBase._shLevel);
        stAtkTag.SetAcademy(stPlayerBase._ucAcademy);
        stAtkTag.SetGID(stPlayerBase._uiGID);
        stAtkTag.SetRoleName(stPlayerBase._sRoleName.Get());

        _stRank.AttackTagUpdate(stAtkTag, iOldOrder, iNewOrder);

        //如果积分有变排名不变 这里没有触发下发 需要战斗那边触发
        if (iNewOrder >= 0 && iOldOrder != iNewOrder)
        {
            stUnit.Clear();
            stUnit._iSubCmd = CMD_MANOR_BATTLE_SUB_TARGET;
            stUnit._uiMapID = stMap.GetMapID();
            stUnit._iTargetCamp = ENM_MANOR_BATTLE_CAMP_ATTACK;
            stInfo.AddUnit(stUnit);
        }
    }
}

int CManorBattleMgr::DeleteTargetListUnit(CPlayerDetailInfo& stPlayerDetail)
{
    //函数返回下发类型 返回0为不需要下发

    int iCamp = _stData.GetClanCamp(stPlayerDetail._stUserClan._uiClanId);
    if (ENM_MANOR_BATTLE_CAMP_NONE == iCamp)
    {
        return 0; //非参赛家族不需删除
    }

    if (ENM_MANOR_BATTLE_CAMP_DEFEND == iCamp) //我所在阵营为防守方
    {
        for (int i = 0; i < _stRank.GetDefendListSize(); ++i)
        {
            CManorBattleDefTag& stDefTag = _stRank.GetDefendTag(i);
            
            if (stDefTag.GetGID() == stPlayerDetail._uiGID)
            {
                if (_stRank.DefendShiftDelOneItem(i) >= 0)
                {
                    return ENM_MANOR_BATTLE_CAMP_DEFEND;
                }
            }
        }
    }
    else if (ENM_MANOR_BATTLE_CAMP_ATTACK == iCamp) //我所在阵营为进攻方
    {
        for (int i = 0; i < _stRank.GetAttackListSize(); ++i)
        {
            CManorBattleAtkTag& stAtkTag = _stRank.GetAttackTag(i);
            
            if (stAtkTag.GetGID() == stPlayerDetail._uiGID)
            {
                if (_stRank.AttackShiftDelOneItem(i) >= 0)
                {
                    return ENM_MANOR_BATTLE_CAMP_ATTACK;
                }
            }
        }
    }

    return 0;
}

void CManorBattleMgr::NotifyTargetList(int iCampTargetChg)
{
    CCmdInnerManorBattle* pstCmd =
        (CCmdInnerManorBattle*)CT_CMDFACTORY->CreateCmd(
            ID_MAIN_INNER_MANOR_BATTLE);
    if (!pstCmd)
    {
        CT_ERROR(("create CCmdInnerManorBattle error"));
        return;
    }

    pstCmd->pstMainCtrl = CMainCtrl::m_pstMain;

    pstCmd->_stAns.Clear();
    pstCmd->_stAns.set_sub_type(CMD_MANOR_BATTLE_SUB_TARGET);

    //主动下发防守方目标列表
    if (ENM_MANOR_BATTLE_CAMP_DEFEND == iCampTargetChg)
    {
        GetDefendTargetList(pstCmd->_stAns);

        for (int i = 0; i < _stRank.GetAttackListSize(); ++i)
        {
            CManorBattleAtkTag& stAtkTag = _stRank.GetAttackTag(i);
            pstCmd->_auiMapUserList.AddOneItem(stAtkTag.GetGID());
        }
    }

    //主动下发进攻方目标列表
    if (ENM_MANOR_BATTLE_CAMP_ATTACK == iCampTargetChg)
    {
        GetAttackTargetList(pstCmd->_stAns);
    
        for (int i = 0; i < _stRank.GetDefendListSize(); ++i)
        {
            CManorBattleDefTag& stDefTag = _stRank.GetDefendTag(i);
            pstCmd->_auiMapUserList.AddOneItem(stDefTag.GetGID());
        }
    }

    pstCmd->_bHasSetAns = true;
    pstCmd->_stUnit._uiMainGID = 0;
    pstCmd->_stUnit._iSubCmd = CMD_MANOR_BATTLE_SUB_TARGET;

    pstCmd->Do(NULL);
}

int CManorBattleMgr::DeadRevive(CPlayerBaseInfo& stPlayerBase,
        CPlayerDetailInfo& stPlayerDetail, CPlayerCacheData& stPlayerCache,
        CManorBattleInfo& stInfo, MsgAnsManorBattle& stAns)
{
    int iRet = 0;
    int iIndex = 0;

    if (!CMainCtrl::m_pstMain->m_stActMgr.IsActOpen(ACT_ID_MANOR_BATTLE))
    {
        return ERROR_ACT_NOT_OPEN; //非活动期间返回错误码
    }

    if (!IsValidStatForMap())
    {
        return ERROR_MANOR_BATTLE_ACT_STAT; //活动阶段错误
    }
    CManorBattleMapUnit& stMap = _stData.GetMap(_stData.GetBattleStat());

    if (!IsRoleInManorBattle(stPlayerBase._uiGID))
    {
        return ERROR_MANOR_BATTLE_NOT_IN_MAP;
    }

    iIndex = CMainCtrl::m_pstMain->m_stActMgr.FindActStatusCfg(
        ACT_ID_MANOR_BATTLE);
    CT_CHECK(iIndex, ERROR_ACT_STATUS_EMPTY_CFG);
    
    CActStatusCfgData& stActStatusCfg =
        CMainCtrl::m_pstMain->m_stActMgr.GetActStatusCfg(iIndex);

    //处理死亡状态
    iIndex = CMainCtrl::m_pstMain->m_stStatusMgr.FindStatus(
        stPlayerCache, stActStatusCfg.GetDeadID());
    if (iIndex < 0)
    {
        return ERROR_MANOR_BATTLE_NOT_IN_DEAD;
    }

    CStatusUnit& stStatusUnit = CMainCtrl::m_pstMain->m_stStatusMgr.GetStatus(
        stPlayerCache, iIndex);

    CManorBattleUnit stUnit;

    //死亡状态到期 不扣金子 主动清除
    if (stStatusUnit.GetEndTime() <= CMainCtrl::m_pstMain->m_iNow)
    {
        CMainCtrl::m_pstMain->m_stStatusMgr.DelStatus(stPlayerCache,
            stActStatusCfg.GetDeadID(), true);
        //这里没有下发给其他角色 因为在上层统一按照错误拦住 不会继续往下走
        return ERROR_STATUS_END_NO_EXPEND;
    }

    UpdateRoleInfo(stPlayerCache);

    int iReviveTimes = stPlayerCache._stManorBattleRole.GetReviveTimes();
    if (iReviveTimes < 0)
    {
        CT_WARNING(("role(%u) revive times error(ReviveTimes=%d)",
            stPlayerBase._uiGID, iReviveTimes));
        iReviveTimes = 0;
    }

    int iGold = GetReviveGold(iReviveTimes + 1);

    //是否金币足够
    iRet = CMainCtrl::m_pstMain->m_stItemMgr.SubGold(stPlayerBase,
        OSS_MONEY_MODULE_55, iGold);
    CHECK_RETURN(iRet);

    CMainCtrl::m_pstMain->m_stNotifyMgr.Notify(stPlayerBase._uiGID,
        NOTIFY_USER_MONEY);

    //释放死亡状态
    CMainCtrl::m_pstMain->m_stStatusMgr.DelStatus(stPlayerCache,
        stActStatusCfg.GetDeadID(), true);

    iIndex = CMainCtrl::m_pstMain->m_stStatusMgr.FindStatus(
        stPlayerCache, stActStatusCfg.GetCoolingID());
    if (iIndex >= 0)
    {
        CStatusUnit& stStatusUnit =
            CMainCtrl::m_pstMain->m_stStatusMgr.GetStatus(
                stPlayerCache, iIndex);

        //战斗冷却没有叠加层数 直接修改到期时间
        stStatusUnit.SetEndTime(0);
    }

    stUnit.Clear();
    stUnit._bNotifySelf = false;
    stUnit._iSubCmd = CMD_MANOR_BATTLE_SUB_REVIVE;
    stUnit._uiMapID = stMap.GetMapID();
    stUnit._uiMainGID = stPlayerBase._uiGID;
    stInfo.AddUnit(stUnit);

    stPlayerCache._stManorBattleRole.SetReviveTimes(iReviveTimes + 1);

    GetCommInfo(stPlayerDetail, stAns);

    GetRoleInfo(stPlayerCache, stAns);

    return 0;
}

void CManorBattleMgr::NotifyAllSceneRole(CManorBattleUnit& stUnit)
{
    if (stUnit._iSubCmd <= 0 || stUnit._uiMapID <= 0)
    {
        CT_ERROR(("NotifyAllSceneRole but sub cmd(%d) and map id(%u) error!",
            stUnit._iSubCmd, stUnit._uiMapID));
        return;
    }

    int iMapUserNum = CMainCtrl::m_pstMain->m_stMapViews.GetAllMapUsersNum(
            stUnit._uiMapID);
    if (iMapUserNum <= 0)
    {
        CT_ERROR(("NotifyAllSceneRole but map(%u) no user(%d)", stUnit._uiMapID,
            iMapUserNum));
        return;
    }

    CCmdInnerManorBattle* pstCmd =
        (CCmdInnerManorBattle*)CT_CMDFACTORY->CreateCmd(
            ID_MAIN_INNER_MANOR_BATTLE);
    if (!pstCmd)
    {
        CT_ERROR(("create CCmdInnerManorBattle error"));
        return;
    }

    pstCmd->pstMainCtrl = CMainCtrl::m_pstMain;

    pstCmd->_bHasSetAns = false;
    pstCmd->_stUnit = stUnit;

    CMainCtrl::m_pstMain->m_stMapViews.GetAllMapUsers(stUnit._uiMapID,
        pstCmd->_auiMapUserList);

    pstCmd->Do(NULL);
}

void CManorBattleMgr::GetSceneInfo(MsgAnsManorBattle& stAns)
{
    MsgManorBattleScene* pstScene = stAns.mutable_scene_info();
    if (!pstScene){CT_ERROR(("MsgManorBattleScene Pointer Null!"));return;}

    pstScene->set_defend_num(_stData.GetDefendRoleNum());
    pstScene->set_attack_num(_stData.GetAttackRoleNum());

    if (_stData.GetClanSize() > 0)
    {
        CManorBattleClanUnit& stClan = _stData.GetClan(0);//约定0元素为防守家族
        pstScene->set_defend_name(stClan.GetClanName());
        pstScene->set_defend_academy(stClan.GetAcademy());
    }
    
    if (_stRank.GetAttackClanSize() > 0)
    {
        CManorBattleClanUnit& stClan = _stRank.GetAttackClan(0);
        pstScene->set_attack_name(stClan.GetClanName());
        pstScene->set_attack_academy(stClan.GetAcademy());
    }

    if (_stData.GetBombStatus() > 0)
    {
        unsigned int uiBuffID =
            CMainCtrl::m_pstMain->m_stStatusMgr.GetBufferID(
                _stData.GetBombStatus());
        if (uiBuffID > 0)
        {
            pstScene->set_bomb_buff_id(uiBuffID);
            pstScene->set_bomb_buff_level(_stData.GetBombLevel());
        }
    }

    if (IsValidStatForMap())
    {
        CManorBattleMapUnit& stMap = _stData.GetMap(_stData.GetBattleStat());
        if (stMap.GetBlessStatus() > 0)
        {
            unsigned int uiBuffID =
                CMainCtrl::m_pstMain->m_stStatusMgr.GetBufferID(
                    stMap.GetBlessStatus());
            if (uiBuffID > 0)
            {
                pstScene->set_bless_buff_id(uiBuffID);
            }
        }
    }
}

void CManorBattleMgr::GetCommInfo(CPlayerDetailInfo& stPlayerDetail,
        MsgAnsManorBattle& stAns)
{
    int iCamp = _stData.GetClanCamp(stPlayerDetail._stUserClan._uiClanId);
    if (ENM_MANOR_BATTLE_CAMP_DEFEND == iCamp)
    {
        stAns.set_is_defend(1);
    }
    else
    {
        stAns.set_is_defend(0);
    }

    stAns.set_act_end_time(
        CMainCtrl::m_pstMain->m_stActMgr.GetEndTime(ACT_ID_MANOR_BATTLE));
    stAns.set_prepare_end_time(_stData.GetStatEndTime());
}

int CManorBattleMgr::GetReviveGold(int iReviveTimes)
{
    //这里返回第x次符石复活需要消耗的符石数量
    if (iReviveTimes <= 5)
    {
        return 5;
    }
    else if (iReviveTimes <= 10)
    {
        return 20;
    }
    else if (iReviveTimes <= 20)
    {
        return 50;
    }
    else
    {
        return 100;
    }
}

//获取个人信息
void CManorBattleMgr::GetRoleInfo(CPlayerCacheData& stPlayerCache,
        MsgAnsManorBattle& stAns)
{
    int iIndex = 0;
    UpdateRoleInfo(stPlayerCache);

    MsgManorBattleRole* pstRoleInfo = stAns.mutable_role_info();
    if (!pstRoleInfo){CT_ERROR(("MsgManorBattleRole Null Pointer!")); return;}

    iIndex = CMainCtrl::m_pstMain->m_stActMgr.FindActStatusCfg(
        ACT_ID_MANOR_BATTLE);
    if (iIndex < 0){CT_ERROR(("Manor Battle act status cfg empty!")); return;}
    
    CActStatusCfgData& stActStatusCfg =
        CMainCtrl::m_pstMain->m_stActMgr.GetActStatusCfg(iIndex);

    iIndex = CMainCtrl::m_pstMain->m_stStatusMgr.FindStatus(
        stPlayerCache, stActStatusCfg.GetDeadID());
    if (iIndex >= 0)
    {
        CStatusUnit& stStatusUnit =
            CMainCtrl::m_pstMain->m_stStatusMgr.GetStatus(stPlayerCache,
                iIndex);

        //死亡状态到期 不扣金子 主动清除
        if (stStatusUnit.GetEndTime() <= CMainCtrl::m_pstMain->m_iNow)
        {
            CMainCtrl::m_pstMain->m_stStatusMgr.DelStatus(stPlayerCache,
                stActStatusCfg.GetDeadID(), true);
            pstRoleInfo->set_expire_time(0);
        }
        else
        {
            pstRoleInfo->set_expire_time(stStatusUnit.GetEndTime());
        }
    }
    else
    {
        pstRoleInfo->set_expire_time(0);
    }

    pstRoleInfo->set_revive_gold(
        GetReviveGold(stPlayerCache._stManorBattleRole.GetReviveTimes() + 1));

    pstRoleInfo->set_series_kill(
        stPlayerCache._stManorBattleRole.GetSeriesKill());
}

//获取怪物信息
void CManorBattleMgr::GetMonsterInfo(int iStatForMon, MsgAnsManorBattle& stAns)
{
    if (!IsValidStatForMon(iStatForMon))
    {
        CT_ERROR(("Manor Battle Battle Stat error!"));
        return;
    }

    MsgManorBattleMonster* pstMonInfo = stAns.mutable_monster_info();
    if (!pstMonInfo){CT_ERROR(("MsgManorBattleMonster Pointer Null!"));return;}

    CManorBattleMonUnit& stMon = _stData.GetMonster(iStatForMon);
    pstMonInfo->set_max_hp(stMon.GetMaxHP());
    pstMonInfo->set_now_hp(stMon.GetHP());
    pstMonInfo->set_level(stMon.GetLevel());
    pstMonInfo->set_group_id(stMon.GetGroupID());
}

void CManorBattleMgr::GetRank(CPlayerCacheData& stPlayerCache,
        MsgAnsManorBattle& stAns)
{ 
    MsgManorBattleRank* pstRank = stAns.mutable_rank_info();
    if (!pstRank){CT_ERROR(("MsgManorBattleRank Pointer Null!"));return;}

    UpdateRoleInfo(stPlayerCache);
    pstRank->set_my_score(stPlayerCache._stManorBattleRole.GetScore());

    for (int i = 0; i < _stRank.GetDefendSize(); ++i)
    {
        MsgRoleScoreUnit* pstUnit = pstRank->add_defend_rank();
        if (!pstUnit){CT_ERROR(("MsgRoleScoreUnit Pointer Null!"));continue;}

        CManorBattleDefUnit& stDefUnit = _stRank.GetDefendUnit(i);
        pstUnit->set_academy(stDefUnit.GetAcademy());
        pstUnit->set_score(stDefUnit.GetScore());
        pstUnit->set_name(stDefUnit.GetRoleName());
        pstUnit->set_gid(stDefUnit.GetGID());
    }

    for (int i = 0; i < _stRank.GetAttackSize(); ++i)
    {
        MsgRoleScoreUnit* pstUnit = pstRank->add_attack_rank();
        if (!pstUnit){CT_ERROR(("MsgRoleScoreUnit Pointer Null!"));continue;}

        CManorBattleAtkUnit& stAtkUnit = _stRank.GetAttackUnit(i);
        pstUnit->set_academy(stAtkUnit.GetAcademy());
        pstUnit->set_score(stAtkUnit.GetScore());
        pstUnit->set_name(stAtkUnit.GetRoleName());
        pstUnit->set_gid(stAtkUnit.GetGID());
    }

    for (int i = 0; i < _stRank.GetAttackClanSize(); ++i)
    {
        MsgClanScoreUnit* pstUnit = pstRank->add_attack_clan();
        if (!pstUnit){CT_ERROR(("MsgClanScoreUnit Pointer Null!"));continue;}

        CManorBattleClanUnit& stClanUnit = _stRank.GetAttackClan(i);
        pstUnit->set_academy(stClanUnit.GetAcademy());
        pstUnit->set_score(stClanUnit.GetScore());
        pstUnit->set_name(stClanUnit.GetClanName());
    }
}

